use crate::error::EasyError;

pub fn encode_u16_be(val :u16) -> [u8;2] {
    [(val >> 8) as u8,  val as u8]
}

pub fn decode_u16_be(i :&[u8]) -> Result<u16,EasyError> {
    if i.len() < 2 {
        Err(EasyError::from(format!("expect 2 bytes, but have {}", i.len())))
    } else {
        Ok(((i[0] as u16) << 8) + i[1] as u16)
    }
}


#[test]
fn test_encode_u16_be(){
    let val_bytes = encode_u16_be(123);
    println!("raw bytes: {:#?}", val_bytes);
    let val_be = decode_u16_be(val_bytes.as_ref()).unwrap();
    println!("val_be: {}", val_be);
}

pub fn encode_u16_le(val :u16) -> [u8;2] {
    [val as u8, (val >> 8) as u8]
}

pub fn decode_u16_le(i :&[u8]) -> Result<u16, EasyError> {
    if i.len() < 2 {
        Err(EasyError::from(format!("expect 2 bytes, but have {}", i.len())))
    } else {
        Ok(((i[1] as u16) << 8) + i[0] as u16)
    }
}

#[test]
fn test_encode_u16_le(){
    let val_bytes = encode_u16_le(123);
    println!("raw bytes: {:#?}", val_bytes);
    let val_be = decode_u16_le(val_bytes.as_ref()).unwrap();
    println!("val_be: {}", val_be);
}

pub fn encode_u32_be(val :u32) -> [u8;4] {
    [
        (val >> 24) as u8,
        (val >> 16) as u8,
        (val >> 8) as u8,
        val as u8,
    ]
}

pub fn decode_u32_be(i :&[u8]) -> Result<u32, EasyError> {
    if i.len() < 4 {
        Err(EasyError::from(format!("expect 4 bytes, but have {}", i.len())))
    } else {
        Ok(((i[0] as u32) << 24)  + ((i[1] as u32) << 16) + ((i[2] as u32) <<  8) + i[3] as u32)
    }
}

#[test]
fn test_encode_u32_be(){
    let val_bytes = encode_u32_be(12345);
    println!("raw bytes: {:?}", val_bytes);
    let val_be = decode_u32_be(val_bytes.as_ref()).unwrap();
    println!("val_be: {}", val_be);
}

pub fn encode_u32_le(val :u32) -> [u8;4] {
    [  val as u8,
        (val >> 8) as u8,
        (val >> 16) as u8,
        (val >> 24) as u8,
    ]
}


pub fn decode_u32_le(i :&[u8]) -> Result<u32, EasyError> {
    if i.len() < 4 {
        Err(EasyError::from(format!("expect 4 bytes, but have {}", i.len())))
    } else {
        Ok(((i[3] as u32) << 24)  + ((i[2] as u32) << 16) + ((i[1] as u32) <<  8) + i[0] as u32)
    }
}

#[test]
fn test_encode_u32_le(){
    let val_u32 = 123456;
    let val_bytes = encode_u32_le(val_u32);
    let val_be = decode_u32_le(val_bytes.as_ref()).unwrap();

    assert_eq!(val_u32, val_be);
}

///////////////////////////////////////////////////////////////////////////////////////////////////
pub fn encode_u64_be(val :u32) -> [u8;8] {
    [
        (val >> 56) as u8,
        (val >> 48) as u8,
        (val >> 40) as u8,
        (val >> 32) as u8,
        (val >> 24) as u8,
        (val >> 16) as u8,
        (val >> 8) as u8,
        val as u8,
    ]
}

pub fn decode_u64_be(i :&[u8]) -> Result<u32, EasyError> {
    if i.len() < 8 {
        Err(EasyError::from(format!("expect 8 bytes, but have {}", i.len())))
    } else {
        Ok( ((i[0] as u32) << 56) +
            ((i[1] as u32) << 48) +
            ((i[2] as u32) << 40) +
            ((i[3] as u32) << 32) +
            ((i[4] as u32) << 24) +
            ((i[5] as u32) << 16) +
            ((i[6] as u32) <<  8) +
            i[7] as u32)
    }
}

pub fn encode_u64_le(val :u32) -> [u8;8] {
    [  val as u8,
        (val >> 8) as u8,
        (val >> 16) as u8,
        (val >> 24) as u8,
        (val >> 32) as u8,
        (val >> 40) as u8,
        (val >> 48) as u8,
        (val >> 56) as u8,
    ]
}


pub fn decode_u64_le(i: &[u8]) -> Result<u32, EasyError> {
    if i.len() < 8 {
        Err(EasyError::from(format!("expect 8 bytes, but have {}", i.len())))
    } else {
        Ok(
                ((i[7] as u32) << 24) +
                ((i[6] as u32) << 24) +
                ((i[5] as u32) << 24) +
                ((i[4] as u32) << 24) +
                ((i[3] as u32) << 24) +
                ((i[2] as u32) << 16) +
                ((i[1] as u32) << 8) +
                i[0] as u32)
    }
}